package com.fengmang.myapplication;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;

import dalvik.system.BaseDexClassLoader;
import dalvik.system.DexClassLoader;

public class PluginManager {
    
    private static final PluginManager ourInstance = new PluginManager();

    private DexClassLoader dexClassLoader;
//    private BaseDexClassLoader dexClassLoader;

    private Resources resources;
    protected Resources.Theme mTheme;

    private PackageInfo packageInfo;
    
    public static PluginManager getInstance(){
        return ourInstance;
    }

    public PluginManager() {
    }

    //用来加载插件
//    public void loadPlugin(Context context) {
//        // 假如这里是从网络获取的插件 我们直接从sd卡获取 然后读取到我们的cache目录
//        String pluginName = "plugin.apk";
//        File filesDir = context.getDir("plugin", Context.MODE_PRIVATE);
//        String filePath = new File(filesDir, pluginName).getAbsolutePath();
//        File file = new File(filePath);
//        if (file.exists()) {
//            file.delete();
//        }
//        FileInputStream is = null;
//        FileOutputStream os = null;
//        //读取的目录
//        try {
//            is = new FileInputStream(new File(Environment.getExternalStorageDirectory(), pluginName));
//            //要输入的目录
//            os = new FileOutputStream(filePath);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        try {
//            int len = 0;
//            byte[] buffer = new byte[1024];
//            while ((len = is.read(buffer)) != -1) {
//                os.write(buffer, 0, len);
//            }
//            File f = new File(filePath);
//            if (f.exists()) {
//                Toast.makeText(context, "dex overwrite", Toast.LENGTH_SHORT).show();
//            }
//            loadPath(context);
//        } catch (Exception e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        } finally {
//            try {
//                os.close();
//                is.close();
//            } catch (Exception e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
//        }
//
//
//    }


    public static void copyFiles(Context context, String fileName, File desFile) {
        InputStream in = null;
        OutputStream out = null;
        try {
//            in = context.getApplicationContext().getAssets().open(fileName);
            in = new FileInputStream(Environment.getExternalStorageDirectory()+ File.separator+"app-debug.apk");

            out = new FileOutputStream(desFile.getAbsolutePath());
            byte[] bytes = new byte[1024];
            int i;
            while ((i = in.read(bytes)) != -1)
                out.write(bytes, 0, i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null)
                    in.close();
                if (out != null)
                    out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public static boolean hasExternalStorage() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    public static File getCacheDir(Context context) {
        File cache;
        if (hasExternalStorage()) {
            cache = context.getExternalCacheDir();
        } else {
            cache = context.getCacheDir();
        }
        if (!cache.exists())
            cache.mkdirs();
        return cache;
    }

    File dir;
    public String copyFiles(Context context, String fileName) {
//        dir = context.getCacheDir();
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//            dir = context.getCodeCacheDir();
//        }
//        dir = context.getDir("plugin", Context.MODE_PRIVATE);
        dir = context.getDir("dex", Context.MODE_PRIVATE);
        String filePath = dir.getAbsolutePath() + File.separator + fileName;
        Log.e("copyFiles===", "==="+filePath);
        try {
            File desFile = new File(filePath);
            if (!desFile.exists()) {
                desFile.createNewFile();
                copyFiles(context, fileName, desFile);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return filePath;

    }



    public void loadPath2(Context context){

        try {
//            String path = "/data/data/com.fengmang.myapplication/app-debug.apk";    //Y
            String path = Environment.getExternalStorageDirectory() + File.separator + "new.apk";    //Y
//            String path = "/data/data/com.fengmang.myapplication/new.apk";    //Y

            packageInfo = context.getPackageManager().getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);

            Log.e("loadPath===0", "==="+packageInfo);

            Toast.makeText(context, "==="+packageInfo, Toast.LENGTH_SHORT).show();

            if(packageInfo==null) return;

            AssetManager manager = AssetManager.class.newInstance();
            Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
//            addAssetPath.setAccessible(true);
            addAssetPath.invoke(manager, path);


//            Method mEnsureStringBlocks = AssetManager.class.getDeclaredMethod("ensureStringBlocks", new Class[O]);
//            mEnsureStringBlocks.setAccessible(true) ;
//            mEnsureStringBlocks.invoke(newAssetManager ew Ob] ect [0]) ;


            resources = new Resources(manager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration());
//            resources = packageManager.getResourcesForApplication(packageInfo.packageName);

            mTheme = resources.newTheme();
            mTheme.setTo(context.getTheme());

            Log.e("loadPath===1", resources+"==="+dexClassLoader);
        } catch (Exception e) {
            Log.e("loadPath===e", "==="+e);
        }
    }

    public Resources getResources(){
        return  resources;
    }

//    public AssetManager getAssets() {
//        return mAssetManager == null ? super.getAssets() : mAssetManager;
//    }

    public Resources.Theme getTheme() {
        return mTheme;
    }

    public BaseDexClassLoader getDexClassLoader(){
        return dexClassLoader;
    }

    public PackageInfo getPackageInfo(){
        return packageInfo;
    }
}
